
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
  <head>
    <meta charset="utf-8" />
    <title>6. 模块 &#8212; Python 3.7.8 文档</title>
    <link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <script type="text/javascript" src="../_static/translations.js"></script>
    
    <script type="text/javascript" src="../_static/sidebar.js"></script>
    
    <link rel="search" type="application/opensearchdescription+xml"
          title="在 Python 3.7.8 文档 中搜索"
          href="../_static/opensearch.xml"/>
    <link rel="author" title="关于这些文档" href="../about.html" />
    <link rel="index" title="索引" href="../genindex.html" />
    <link rel="search" title="搜索" href="../search.html" />
    <link rel="copyright" title="版权所有" href="../copyright.html" />
    <link rel="next" title="7. 输入输出" href="inputoutput.html" />
    <link rel="prev" title="5. 数据结构" href="datastructures.html" />
    <link rel="shortcut icon" type="image/png" href="../_static/py.png" />
    <link rel="canonical" href="https://docs.python.org/3/tutorial/modules.html" />
    
    <script type="text/javascript" src="../_static/copybutton.js"></script>
    
    
    
    
    <style>
      @media only screen {
        table.full-width-table {
            width: 100%;
        }
      }
    </style>
 

  </head><body>
  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="inputoutput.html" title="7. 输入输出"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="datastructures.html" title="5. 数据结构"
             accesskey="P">上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 教程</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>    

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="modules">
<span id="tut-modules"></span><h1><span class="section-number">6. </span>模块<a class="headerlink" href="#modules" title="永久链接至标题">¶</a></h1>
<p>如果你从Python解释器退出并再次进入，之前的定义（函数和变量）都会丢失。因此，如果你想编写一个稍长些的程序，最好使用文本编辑器为解释器准备输入并将该文件作为输入运行。这被称作编写 <em>脚本</em> 。随着程序变得越来越长，你或许会想把它拆分成几个文件，以方便维护。你亦或想在不同的程序中使用一个便捷的函数， 而不必把这个函数复制到每一个程序中去。</p>
<p>为支持这些，Python有一种方法可以把定义放在一个文件里，并在脚本或解释器的交互式实例中使用它们。这样的文件被称作 <em>模块</em> ；模块中的定义可以 <em>导入</em> 到其它模块或者 <em>主</em> 模块（你在顶级和计算器模式下执行的脚本中可以访问的变量集合）。</p>
<p>模块是一个包含Python定义和语句的文件。文件名就是模块名后跟文件后缀 <code class="file docutils literal notranslate"><span class="pre">.py</span></code> 。在一个模块内部，模块名（作为一个字符串）可以通过全局变量 <code class="docutils literal notranslate"><span class="pre">__name__</span></code> 的值获得。例如，使用你最喜爱的文本编辑器在当前目录下创建一个名为 <code class="file docutils literal notranslate"><span class="pre">fibo.py</span></code> 的文件， 文件中含有以下内容:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># Fibonacci numbers module</span>

<span class="k">def</span> <span class="nf">fib</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>    <span class="c1"># write Fibonacci series up to n</span>
    <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
    <span class="k">while</span> <span class="n">a</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
        <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span>
    <span class="nb">print</span><span class="p">()</span>

<span class="k">def</span> <span class="nf">fib2</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>   <span class="c1"># return Fibonacci series up to n</span>
    <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
    <span class="k">while</span> <span class="n">a</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">:</span>
        <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
        <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span>
    <span class="k">return</span> <span class="n">result</span>
</pre></div>
</div>
<p>现在进入Python解释器，并用以下命令导入该模块:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">fibo</span>
</pre></div>
</div>
<p>在当前的符号表中，这并不会直接进入到定义在 <code class="docutils literal notranslate"><span class="pre">fibo</span></code> 函数内的名称；它只是进入到模块名 <code class="docutils literal notranslate"><span class="pre">fibo</span></code> 中。你可以用模块名访问这些函数:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">fibo</span><span class="o">.</span><span class="n">fib</span><span class="p">(</span><span class="mi">1000</span><span class="p">)</span>
<span class="go">0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fibo</span><span class="o">.</span><span class="n">fib2</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
<span class="go">[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fibo</span><span class="o">.</span><span class="vm">__name__</span>
<span class="go">&#39;fibo&#39;</span>
</pre></div>
</div>
<p>如果你想经常使用某个函数，你可以把它赋值给一个局部变量:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">fib</span> <span class="o">=</span> <span class="n">fibo</span><span class="o">.</span><span class="n">fib</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fib</span><span class="p">(</span><span class="mi">500</span><span class="p">)</span>
<span class="go">0 1 1 2 3 5 8 13 21 34 55 89 144 233 377</span>
</pre></div>
</div>
<div class="section" id="more-on-modules">
<span id="tut-moremodules"></span><h2><span class="section-number">6.1. </span>更多有关模块的信息<a class="headerlink" href="#more-on-modules" title="永久链接至标题">¶</a></h2>
<p>模块可以包含可执行的语句以及函数定义。这些语句用于初始化模块。它们仅在模块 <em>第一次</em> 在 import 语句中被导入时才执行。 <a class="footnote-reference brackets" href="#id2" id="id1">1</a> (当文件被当作脚本运行时，它们也会执行。)</p>
<p>每个模块都有它自己的私有符号表，该表用作模块中定义的所有函数的全局符号表。因此，模块的作者可以在模块内使用全局变量，而不必担心与用户的全局变量发生意外冲突。另一方面，如果你知道自己在做什么，则可以用跟访问模块内的函数的同样标记方法，去访问一个模块的全局变量，<code class="docutils literal notranslate"><span class="pre">modname.itemname</span></code>。</p>
<p>模块可以导入其它模块。习惯上但不要求把所有 <a class="reference internal" href="../reference/simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句放在模块（或脚本）的开头。被导入的模块名存放在调入模块的全局符号表中。</p>
<p><a class="reference internal" href="../reference/simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句有一个变体，它可以把名字从一个被调模块内直接导入到现模块的符号表里。例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">fibo</span> <span class="kn">import</span> <span class="n">fib</span><span class="p">,</span> <span class="n">fib2</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fib</span><span class="p">(</span><span class="mi">500</span><span class="p">)</span>
<span class="go">0 1 1 2 3 5 8 13 21 34 55 89 144 233 377</span>
</pre></div>
</div>
<p>这并不会把被调模块名引入到局部变量表里（因此在这个例子里，<code class="docutils literal notranslate"><span class="pre">fibo</span></code> 是未被定义的）。</p>
<p>还有一个变体甚至可以导入模块内定义的所有名称:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">fibo</span> <span class="kn">import</span> <span class="o">*</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fib</span><span class="p">(</span><span class="mi">500</span><span class="p">)</span>
<span class="go">0 1 1 2 3 5 8 13 21 34 55 89 144 233 377</span>
</pre></div>
</div>
<p>这会调入所有非以下划线（<code class="docutils literal notranslate"><span class="pre">_</span></code>）开头的名称。 在多数情况下，Python程序员都不会使用这个功能，因为它在解释器中引入了一组未知的名称，而它们很可能会覆盖一些你已经定义过的东西。</p>
<p>注意通常情况下从一个模块或者包内调入 <code class="docutils literal notranslate"><span class="pre">*</span></code> 的做法是不太被接受的， 因为这通常会导致代码的可读性很差。不过，在交互式编译器中为了节省打字可以这么用。</p>
<p>如果模块名称之后带有 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">as</span></code>，则跟在 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">as</span></code> 之后的名称将直接绑定到所导入的模块。</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">fibo</span> <span class="k">as</span> <span class="nn">fib</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fib</span><span class="o">.</span><span class="n">fib</span><span class="p">(</span><span class="mi">500</span><span class="p">)</span>
<span class="go">0 1 1 2 3 5 8 13 21 34 55 89 144 233 377</span>
</pre></div>
</div>
<p>这会和 <code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">fibo</span></code> 方式一样有效地调入模块， 唯一的区别是它以 <code class="docutils literal notranslate"><span class="pre">fib</span></code> 的名称存在的。</p>
<p>这种方式也可以在用到 <a class="reference internal" href="../reference/simple_stmts.html#from"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">from</span></code></a> 的时候使用，并会有类似的效果:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">fibo</span> <span class="kn">import</span> <span class="n">fib</span> <span class="k">as</span> <span class="n">fibonacci</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fibonacci</span><span class="p">(</span><span class="mi">500</span><span class="p">)</span>
<span class="go">0 1 1 2 3 5 8 13 21 34 55 89 144 233 377</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>出于效率的考虑，每个模块在每个解释器会话中只被导入一次。因此，如果你更改了你的模块，则必须重新启动解释器， 或者，如果它只是一个要交互式地测试的模块，请使用 <a class="reference internal" href="../library/importlib.html#importlib.reload" title="importlib.reload"><code class="xref py py-func docutils literal notranslate"><span class="pre">importlib.reload()</span></code></a>，例如 <code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">importlib;</span> <span class="pre">importlib.reload(modulename)</span></code>。</p>
</div>
<div class="section" id="executing-modules-as-scripts">
<span id="tut-modulesasscripts"></span><h3><span class="section-number">6.1.1. </span>以脚本的方式执行模块<a class="headerlink" href="#executing-modules-as-scripts" title="永久链接至标题">¶</a></h3>
<p>当你用下面方式运行一个Python模块:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="n">fibo</span><span class="o">.</span><span class="n">py</span> <span class="o">&lt;</span><span class="n">arguments</span><span class="o">&gt;</span>
</pre></div>
</div>
<p>模块里的代码会被执行，就好像你导入了模块一样，但是 <code class="docutils literal notranslate"><span class="pre">__name__</span></code> 被赋值为 <code class="docutils literal notranslate"><span class="pre">&quot;__main__&quot;</span></code>。 这意味着通过在你的模块末尾添加这些代码:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">sys</span>
    <span class="n">fib</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
</pre></div>
</div>
<p>你既可以把这个文件当作脚本又可当作一个可调入的模块来使用， 因为那段解析命令行的代码只有在当模块是以“main”文件的方式执行的时候才会运行:</p>
<div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$</span> python fibo.py <span class="m">50</span>
<span class="go">0 1 1 2 3 5 8 13 21 34</span>
</pre></div>
</div>
<p>如果模块是被导入的，那些代码是不运行的:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">fibo</span>
<span class="go">&gt;&gt;&gt;</span>
</pre></div>
</div>
<p>这经常用于为模块提供一个方便的用户接口，或用于测试（以脚本的方式运行模块从而执行一些测试套件）。</p>
</div>
<div class="section" id="the-module-search-path">
<span id="tut-searchpath"></span><h3><span class="section-number">6.1.2. </span>模块搜索路径<a class="headerlink" href="#the-module-search-path" title="永久链接至标题">¶</a></h3>
<p id="index-0">当一个名为 <code class="xref py py-mod docutils literal notranslate"><span class="pre">spam</span></code> 的模块被导入的时候，解释器首先寻找具有该名称的内置模块。如果没有找到，然后解释器从 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 变量给出的目录列表里寻找名为 <code class="file docutils literal notranslate"><span class="pre">spam.py</span></code> 的文件。<a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 初始有这些目录地址:</p>
<ul class="simple">
<li><p>包含输入脚本的目录（或者未指定文件时的当前目录）。</p></li>
<li><p><span class="target" id="index-14"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONPATH"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONPATH</span></code></a> （一个包含目录名称的列表，它和shell变量 <span class="target" id="index-15"></span><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PATH</span></code> 有一样的语法）。</p></li>
<li><p>取决于安装的默认设置</p></li>
</ul>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>在支持符号链接的文件系统上，包含输入脚本的目录是在追加符号链接后才计算出来的。换句话说，包含符号链接的目录并 <strong>没有</strong> 被添加到模块的搜索路径上。</p>
</div>
<p>在初始化后，Python程序可以更改 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a>。包含正在运行脚本的文件目录被放在搜索路径的开头处， 在标准库路径之前。这意味着将加载此目录里的脚本，而不是标准库中的同名模块。 除非有意更换，否则这是错误。更多信息请参阅 <a class="reference internal" href="#tut-standardmodules"><span class="std std-ref">标准模块</span></a>。</p>
</div>
<div class="section" id="compiled-python-files">
<h3><span class="section-number">6.1.3. </span>“编译过的”Python文件<a class="headerlink" href="#compiled-python-files" title="永久链接至标题">¶</a></h3>
<p>为了加速模块载入，Python在 <code class="docutils literal notranslate"><span class="pre">__pycache__</span></code> 目录里缓存了每个模块的编译后版本，名称为 <code class="file docutils literal notranslate"><span class="pre">module.</span><em><span class="pre">version</span></em><span class="pre">.pyc</span></code> ，其中名称中的版本字段对编译文件的格式进行编码； 它一般使用Python版本号。例如，在CPython版本3.3中，spam.py的编译版本将被缓存为 <code class="docutils literal notranslate"><span class="pre">__pycache__/spam.cpython-33.pyc</span></code>。此命名约定允许来自不同发行版和不同版本的Python的已编译模块共存。</p>
<p>Python根据编译版本检查源的修改日期，以查看它是否已过期并需要重新编译。这是一个完全自动化的过程。此外，编译的模块与平台无关，因此可以在具有不同体系结构的系统之间共享相同的库。</p>
<p>Python在两种情况下不会检查缓存。首先，对于从命令行直接载入的模块，它从来都是重新编译并且不存储编译结果；其次，如果没有源模块，它不会检查缓存。为了支持无源文件（仅编译）发行版本， 编译模块必须是在源目录下，并且绝对不能有源模块。</p>
<p>给专业人士的一些小建议:</p>
<ul class="simple">
<li><p>你可以在Python命令中使用 <a class="reference internal" href="../using/cmdline.html#cmdoption-o"><code class="xref std std-option docutils literal notranslate"><span class="pre">-O</span></code></a> 或者 <a class="reference internal" href="../using/cmdline.html#cmdoption-oo"><code class="xref std std-option docutils literal notranslate"><span class="pre">-OO</span></code></a> 开关， 以减小编译后模块的大小。 <code class="docutils literal notranslate"><span class="pre">-O</span></code> 开关去除断言语句，<code class="docutils literal notranslate"><span class="pre">-OO</span></code> 开关同时去除断言语句和 __doc__ 字符串。由于有些程序可能依赖于这些，你应当只在清楚自己在做什么时才使用这个选项。“优化过的”模块有一个 <code class="docutils literal notranslate"><span class="pre">opt-</span></code> 标签并且通常小些。将来的发行版本或许会更改优化的效果。</p></li>
<li><p>一个从 <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> 文件读出的程序并不会比它从 <code class="docutils literal notranslate"><span class="pre">.py</span></code> 读出时运行的更快，<code class="docutils literal notranslate"><span class="pre">.pyc</span></code> 文件唯一快的地方在于载入速度。</p></li>
<li><p><a class="reference internal" href="../library/compileall.html#module-compileall" title="compileall: Tools for byte-compiling all Python source files in a directory tree."><code class="xref py py-mod docutils literal notranslate"><span class="pre">compileall</span></code></a> 模块可以为一个目录下的所有模块创建.pyc文件。</p></li>
<li><p>关于这个过程，<span class="target" id="index-16"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-3147"><strong>PEP 3147</strong></a> 中有更多细节，包括一个决策流程图。</p></li>
</ul>
</div>
</div>
<div class="section" id="standard-modules">
<span id="tut-standardmodules"></span><h2><span class="section-number">6.2. </span>标准模块<a class="headerlink" href="#standard-modules" title="永久链接至标题">¶</a></h2>
<p id="index-4">Python附带了一个标准模块库，在单独的文档Python库参考（以下称为“库参考”）中进行了描述。一些模块内置于解释器中；它们提供对不属于语言核心但仍然内置的操作的访问，以提高效率或提供对系统调用等操作系统原语的访问。这些模块的集合是一个配置选项，它也取决于底层平台。例如，<a class="reference internal" href="../library/winreg.html#module-winreg" title="winreg: Routines and objects for manipulating the Windows registry. (Windows)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">winreg</span></code></a> 模块只在Windows操作系统上提供。一个特别值得注意的模块 <a class="reference internal" href="../library/sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal notranslate"><span class="pre">sys</span></code></a>，它被内嵌到每一个Python解释器中。变量 <code class="docutils literal notranslate"><span class="pre">sys.ps1</span></code> 和 <code class="docutils literal notranslate"><span class="pre">sys.ps2</span></code> 定义用作主要和辅助提示的字符串:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">ps1</span>
<span class="go">&#39;&gt;&gt;&gt; &#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">ps2</span>
<span class="go">&#39;... &#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">ps1</span> <span class="o">=</span> <span class="s1">&#39;C&gt; &#39;</span>
<span class="go">C&gt; print(&#39;Yuck!&#39;)</span>
<span class="go">Yuck!</span>
<span class="go">C&gt;</span>
</pre></div>
</div>
<p>这两个变量只有在编译器是交互模式下才被定义。</p>
<p><code class="docutils literal notranslate"><span class="pre">sys.path</span></code> 变量是一个字符串列表，用于确定解释器的模块搜索路径。该变量被初始化为从环境变量 <span class="target" id="index-17"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONPATH"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONPATH</span></code></a> 获取的默认路径，或者如果 <span class="target" id="index-18"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONPATH"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONPATH</span></code></a> 未设置，则从内置默认路径初始化。你可以使用标准列表操作对其进行修改:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;/ufs/guido/lib/python&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="the-dir-function">
<span id="tut-dir"></span><h2><span class="section-number">6.3. </span><a class="reference internal" href="../library/functions.html#dir" title="dir"><code class="xref py py-func docutils literal notranslate"><span class="pre">dir()</span></code></a> 函数<a class="headerlink" href="#the-dir-function" title="永久链接至标题">¶</a></h2>
<p>内置函数 <a class="reference internal" href="../library/functions.html#dir" title="dir"><code class="xref py py-func docutils literal notranslate"><span class="pre">dir()</span></code></a> 用于查找模块定义的名称。 它返回一个排序过的字符串列表:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">fibo</span><span class="o">,</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">(</span><span class="n">fibo</span><span class="p">)</span>
<span class="go">[&#39;__name__&#39;, &#39;fib&#39;, &#39;fib2&#39;]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">(</span><span class="n">sys</span><span class="p">)</span>  
<span class="go">[&#39;__displayhook__&#39;, &#39;__doc__&#39;, &#39;__excepthook__&#39;, &#39;__loader__&#39;, &#39;__name__&#39;,</span>
<span class="go"> &#39;__package__&#39;, &#39;__stderr__&#39;, &#39;__stdin__&#39;, &#39;__stdout__&#39;,</span>
<span class="go"> &#39;_clear_type_cache&#39;, &#39;_current_frames&#39;, &#39;_debugmallocstats&#39;, &#39;_getframe&#39;,</span>
<span class="go"> &#39;_home&#39;, &#39;_mercurial&#39;, &#39;_xoptions&#39;, &#39;abiflags&#39;, &#39;api_version&#39;, &#39;argv&#39;,</span>
<span class="go"> &#39;base_exec_prefix&#39;, &#39;base_prefix&#39;, &#39;builtin_module_names&#39;, &#39;byteorder&#39;,</span>
<span class="go"> &#39;call_tracing&#39;, &#39;callstats&#39;, &#39;copyright&#39;, &#39;displayhook&#39;,</span>
<span class="go"> &#39;dont_write_bytecode&#39;, &#39;exc_info&#39;, &#39;excepthook&#39;, &#39;exec_prefix&#39;,</span>
<span class="go"> &#39;executable&#39;, &#39;exit&#39;, &#39;flags&#39;, &#39;float_info&#39;, &#39;float_repr_style&#39;,</span>
<span class="go"> &#39;getcheckinterval&#39;, &#39;getdefaultencoding&#39;, &#39;getdlopenflags&#39;,</span>
<span class="go"> &#39;getfilesystemencoding&#39;, &#39;getobjects&#39;, &#39;getprofile&#39;, &#39;getrecursionlimit&#39;,</span>
<span class="go"> &#39;getrefcount&#39;, &#39;getsizeof&#39;, &#39;getswitchinterval&#39;, &#39;gettotalrefcount&#39;,</span>
<span class="go"> &#39;gettrace&#39;, &#39;hash_info&#39;, &#39;hexversion&#39;, &#39;implementation&#39;, &#39;int_info&#39;,</span>
<span class="go"> &#39;intern&#39;, &#39;maxsize&#39;, &#39;maxunicode&#39;, &#39;meta_path&#39;, &#39;modules&#39;, &#39;path&#39;,</span>
<span class="go"> &#39;path_hooks&#39;, &#39;path_importer_cache&#39;, &#39;platform&#39;, &#39;prefix&#39;, &#39;ps1&#39;,</span>
<span class="go"> &#39;setcheckinterval&#39;, &#39;setdlopenflags&#39;, &#39;setprofile&#39;, &#39;setrecursionlimit&#39;,</span>
<span class="go"> &#39;setswitchinterval&#39;, &#39;settrace&#39;, &#39;stderr&#39;, &#39;stdin&#39;, &#39;stdout&#39;,</span>
<span class="go"> &#39;thread_info&#39;, &#39;version&#39;, &#39;version_info&#39;, &#39;warnoptions&#39;]</span>
</pre></div>
</div>
<p>如果没有参数，<a class="reference internal" href="../library/functions.html#dir" title="dir"><code class="xref py py-func docutils literal notranslate"><span class="pre">dir()</span></code></a> 会列出你当前定义的名称:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">fibo</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fib</span> <span class="o">=</span> <span class="n">fibo</span><span class="o">.</span><span class="n">fib</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">[&#39;__builtins__&#39;, &#39;__name__&#39;, &#39;a&#39;, &#39;fib&#39;, &#39;fibo&#39;, &#39;sys&#39;]</span>
</pre></div>
</div>
<p>注意：它列出所有类型的名称：变量，模块，函数，等等。</p>
<p id="index-7"><a class="reference internal" href="../library/functions.html#dir" title="dir"><code class="xref py py-func docutils literal notranslate"><span class="pre">dir()</span></code></a> 不会列出内置函数和变量的名称。如果你想要这些，它们的定义是在标准模块 <a class="reference internal" href="../library/builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal notranslate"><span class="pre">builtins</span></code></a> 中:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">builtins</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">(</span><span class="n">builtins</span><span class="p">)</span>  
<span class="go">[&#39;ArithmeticError&#39;, &#39;AssertionError&#39;, &#39;AttributeError&#39;, &#39;BaseException&#39;,</span>
<span class="go"> &#39;BlockingIOError&#39;, &#39;BrokenPipeError&#39;, &#39;BufferError&#39;, &#39;BytesWarning&#39;,</span>
<span class="go"> &#39;ChildProcessError&#39;, &#39;ConnectionAbortedError&#39;, &#39;ConnectionError&#39;,</span>
<span class="go"> &#39;ConnectionRefusedError&#39;, &#39;ConnectionResetError&#39;, &#39;DeprecationWarning&#39;,</span>
<span class="go"> &#39;EOFError&#39;, &#39;Ellipsis&#39;, &#39;EnvironmentError&#39;, &#39;Exception&#39;, &#39;False&#39;,</span>
<span class="go"> &#39;FileExistsError&#39;, &#39;FileNotFoundError&#39;, &#39;FloatingPointError&#39;,</span>
<span class="go"> &#39;FutureWarning&#39;, &#39;GeneratorExit&#39;, &#39;IOError&#39;, &#39;ImportError&#39;,</span>
<span class="go"> &#39;ImportWarning&#39;, &#39;IndentationError&#39;, &#39;IndexError&#39;, &#39;InterruptedError&#39;,</span>
<span class="go"> &#39;IsADirectoryError&#39;, &#39;KeyError&#39;, &#39;KeyboardInterrupt&#39;, &#39;LookupError&#39;,</span>
<span class="go"> &#39;MemoryError&#39;, &#39;NameError&#39;, &#39;None&#39;, &#39;NotADirectoryError&#39;, &#39;NotImplemented&#39;,</span>
<span class="go"> &#39;NotImplementedError&#39;, &#39;OSError&#39;, &#39;OverflowError&#39;,</span>
<span class="go"> &#39;PendingDeprecationWarning&#39;, &#39;PermissionError&#39;, &#39;ProcessLookupError&#39;,</span>
<span class="go"> &#39;ReferenceError&#39;, &#39;ResourceWarning&#39;, &#39;RuntimeError&#39;, &#39;RuntimeWarning&#39;,</span>
<span class="go"> &#39;StopIteration&#39;, &#39;SyntaxError&#39;, &#39;SyntaxWarning&#39;, &#39;SystemError&#39;,</span>
<span class="go"> &#39;SystemExit&#39;, &#39;TabError&#39;, &#39;TimeoutError&#39;, &#39;True&#39;, &#39;TypeError&#39;,</span>
<span class="go"> &#39;UnboundLocalError&#39;, &#39;UnicodeDecodeError&#39;, &#39;UnicodeEncodeError&#39;,</span>
<span class="go"> &#39;UnicodeError&#39;, &#39;UnicodeTranslateError&#39;, &#39;UnicodeWarning&#39;, &#39;UserWarning&#39;,</span>
<span class="go"> &#39;ValueError&#39;, &#39;Warning&#39;, &#39;ZeroDivisionError&#39;, &#39;_&#39;, &#39;__build_class__&#39;,</span>
<span class="go"> &#39;__debug__&#39;, &#39;__doc__&#39;, &#39;__import__&#39;, &#39;__name__&#39;, &#39;__package__&#39;, &#39;abs&#39;,</span>
<span class="go"> &#39;all&#39;, &#39;any&#39;, &#39;ascii&#39;, &#39;bin&#39;, &#39;bool&#39;, &#39;bytearray&#39;, &#39;bytes&#39;, &#39;callable&#39;,</span>
<span class="go"> &#39;chr&#39;, &#39;classmethod&#39;, &#39;compile&#39;, &#39;complex&#39;, &#39;copyright&#39;, &#39;credits&#39;,</span>
<span class="go"> &#39;delattr&#39;, &#39;dict&#39;, &#39;dir&#39;, &#39;divmod&#39;, &#39;enumerate&#39;, &#39;eval&#39;, &#39;exec&#39;, &#39;exit&#39;,</span>
<span class="go"> &#39;filter&#39;, &#39;float&#39;, &#39;format&#39;, &#39;frozenset&#39;, &#39;getattr&#39;, &#39;globals&#39;, &#39;hasattr&#39;,</span>
<span class="go"> &#39;hash&#39;, &#39;help&#39;, &#39;hex&#39;, &#39;id&#39;, &#39;input&#39;, &#39;int&#39;, &#39;isinstance&#39;, &#39;issubclass&#39;,</span>
<span class="go"> &#39;iter&#39;, &#39;len&#39;, &#39;license&#39;, &#39;list&#39;, &#39;locals&#39;, &#39;map&#39;, &#39;max&#39;, &#39;memoryview&#39;,</span>
<span class="go"> &#39;min&#39;, &#39;next&#39;, &#39;object&#39;, &#39;oct&#39;, &#39;open&#39;, &#39;ord&#39;, &#39;pow&#39;, &#39;print&#39;, &#39;property&#39;,</span>
<span class="go"> &#39;quit&#39;, &#39;range&#39;, &#39;repr&#39;, &#39;reversed&#39;, &#39;round&#39;, &#39;set&#39;, &#39;setattr&#39;, &#39;slice&#39;,</span>
<span class="go"> &#39;sorted&#39;, &#39;staticmethod&#39;, &#39;str&#39;, &#39;sum&#39;, &#39;super&#39;, &#39;tuple&#39;, &#39;type&#39;, &#39;vars&#39;,</span>
<span class="go"> &#39;zip&#39;]</span>
</pre></div>
</div>
</div>
<div class="section" id="packages">
<span id="tut-packages"></span><h2><span class="section-number">6.4. </span>包<a class="headerlink" href="#packages" title="永久链接至标题">¶</a></h2>
<p>包是一种通过用“带点号的模块名”来构造 Python 模块命名空间的方法。 例如，模块名 <code class="xref py py-mod docutils literal notranslate"><span class="pre">A.B</span></code> 表示 <code class="docutils literal notranslate"><span class="pre">A</span></code> 包中名为 <code class="docutils literal notranslate"><span class="pre">B</span></code> 的子模块。正如模块的使用使得不同模块的作者不必担心彼此的全局变量名称一样，使用加点的模块名可以使得 NumPy 或 Pillow 等多模块软件包的作者不必担心彼此的模块名称一样。</p>
<p>假设你想为声音文件和声音数据的统一处理，设计一个模块集合（一个“包”）。由于存在很多不同的声音文件格式（通常由它们的扩展名来识别，例如：<code class="file docutils literal notranslate"><span class="pre">.wav</span></code>， <code class="file docutils literal notranslate"><span class="pre">.aiff</span></code>， <code class="file docutils literal notranslate"><span class="pre">.au</span></code>），因此为了不同文件格式间的转换，你可能需要创建和维护一个不断增长的模块集合。 你可能还想对声音数据还做很多不同的处理（例如，混声，添加回声，使用均衡器功能，创造人工立体声效果）， 因此为了实现这些处理，你将另外写一个无穷尽的模块流。这是你的包的可能结构（以分层文件系统的形式表示）：</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>sound/                          Top-level package
      __init__.py               Initialize the sound package
      formats/                  Subpackage for file format conversions
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  Subpackage for sound effects
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  Subpackage for filters
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...
</pre></div>
</div>
<p>当导入这个包时，Python搜索 <code class="docutils literal notranslate"><span class="pre">sys.path</span></code> 里的目录，查找包的子目录。</p>
<p>必须要有 <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> 文件才能让 Python 将包含该文件的目录当作包。 这样可以防止具有通常名称例如 <code class="docutils literal notranslate"><span class="pre">string</span></code> 的目录在无意中隐藏稍后在模块搜索路径上出现的有效模块。 在最简单的情况下，<code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> 可以只是一个空文件，但它也可以执行包的初始化代码或设置 <code class="docutils literal notranslate"><span class="pre">__all__</span></code> 变量，具体将在后文介绍。</p>
<p>包的用户可以从包中导入单个模块，例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sound.effects.echo</span>
</pre></div>
</div>
<p>这会加载子模块 <code class="xref py py-mod docutils literal notranslate"><span class="pre">sound.effects.echo</span></code> 。但引用它时必须使用它的全名。</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">sound</span><span class="o">.</span><span class="n">effects</span><span class="o">.</span><span class="n">echo</span><span class="o">.</span><span class="n">echofilter</span><span class="p">(</span><span class="nb">input</span><span class="p">,</span> <span class="n">output</span><span class="p">,</span> <span class="n">delay</span><span class="o">=</span><span class="mf">0.7</span><span class="p">,</span> <span class="n">atten</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
</pre></div>
</div>
<p>导入子模块的另一种方法是</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">sound.effects</span> <span class="kn">import</span> <span class="n">echo</span>
</pre></div>
</div>
<p>这也会加载子模块 <code class="xref py py-mod docutils literal notranslate"><span class="pre">echo</span></code> ，并使其在没有包前缀的情况下可用，因此可以按如下方式使用:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">echo</span><span class="o">.</span><span class="n">echofilter</span><span class="p">(</span><span class="nb">input</span><span class="p">,</span> <span class="n">output</span><span class="p">,</span> <span class="n">delay</span><span class="o">=</span><span class="mf">0.7</span><span class="p">,</span> <span class="n">atten</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
</pre></div>
</div>
<p>另一种形式是直接导入所需的函数或变量:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">sound.effects.echo</span> <span class="kn">import</span> <span class="n">echofilter</span>
</pre></div>
</div>
<p>同样，这也会加载子模块 <code class="xref py py-mod docutils literal notranslate"><span class="pre">echo</span></code>，但这会使其函数 <code class="xref py py-func docutils literal notranslate"><span class="pre">echofilter()</span></code> 直接可用:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">echofilter</span><span class="p">(</span><span class="nb">input</span><span class="p">,</span> <span class="n">output</span><span class="p">,</span> <span class="n">delay</span><span class="o">=</span><span class="mf">0.7</span><span class="p">,</span> <span class="n">atten</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
</pre></div>
</div>
<p>请注意，当使用 <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">package</span> <span class="pre">import</span> <span class="pre">item</span></code> 时，item可以是包的子模块（或子包），也可以是包中定义的其他名称，如函数，类或变量。 <code class="docutils literal notranslate"><span class="pre">import</span></code> 语句首先测试是否在包中定义了item；如果没有，它假定它是一个模块并尝试加载它。如果找不到它，则引发 <a class="reference internal" href="../library/exceptions.html#ImportError" title="ImportError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ImportError</span></code></a> 异常。</p>
<p>相反，当使用 <code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">item.subitem.subsubitem</span></code> 这样的语法时，除了最后一项之外的每一项都必须是一个包；最后一项可以是模块或包，但不能是前一项中定义的类或函数或变量。</p>
<div class="section" id="importing-from-a-package">
<span id="tut-pkg-import-star"></span><h3><span class="section-number">6.4.1. </span>从包中导入 *<a class="headerlink" href="#importing-from-a-package" title="永久链接至标题">¶</a></h3>
<p id="index-8">当用户写 <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">sound.effects</span> <span class="pre">import</span> <span class="pre">*</span></code> 会发生什么？理想情况下，人们希望这会以某种方式传递给文件系统，找到包中存在哪些子模块，并将它们全部导入。这可能需要很长时间，导入子模块可能会产生不必要的副作用，这种副作用只有在显式导入子模块时才会发生。</p>
<p>唯一的解决方案是让包作者提供一个包的显式索引。<a class="reference internal" href="../reference/simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句使用下面的规范：如果一个包的 <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> 代码定义了一个名为 <code class="docutils literal notranslate"><span class="pre">__all__</span></code> 的列表，它会被视为在遇到 <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">package</span> <span class="pre">import</span> <span class="pre">*</span></code> 时应该导入的模块名列表。在发布该包的新版本时，包作者可以决定是否让此列表保持更新。包作者如果认为从他们的包中导入 * 的操作没有必要被使用，也可以决定不支持此列表。例如，文件 <code class="file docutils literal notranslate"><span class="pre">sound/effects/__init__.py</span></code> 可以包含以下代码:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;echo&quot;</span><span class="p">,</span> <span class="s2">&quot;surround&quot;</span><span class="p">,</span> <span class="s2">&quot;reverse&quot;</span><span class="p">]</span>
</pre></div>
</div>
<p>这意味着 <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">sound.effects</span> <span class="pre">import</span> <span class="pre">*</span></code> 将导入 <code class="xref py py-mod docutils literal notranslate"><span class="pre">sound</span></code> 包的三个命名子模块。</p>
<p>如果没有定义 <code class="docutils literal notranslate"><span class="pre">__all__</span></code>，<code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">sound.effects</span> <span class="pre">import</span> <span class="pre">*</span></code> 语句 <em>不</em> 会从包 <code class="xref py py-mod docutils literal notranslate"><span class="pre">sound.effects</span></code> 中导入所有子模块到当前命名空间；它只确保导入了包 <code class="xref py py-mod docutils literal notranslate"><span class="pre">sound.effects</span></code> （可能运行任何在 <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> 中的初始化代码），然后导入包中定义的任何名称。这包括 <code class="file docutils literal notranslate"><span class="pre">__init__.py`</span></code> 定义的任何名称（以及显式加载的子模块）。它还包括由之前的 <a class="reference internal" href="../reference/simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句显式加载的包的任何子模块。思考下面的代码:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sound.effects.echo</span>
<span class="kn">import</span> <span class="nn">sound.effects.surround</span>
<span class="kn">from</span> <span class="nn">sound.effects</span> <span class="kn">import</span> <span class="o">*</span>
</pre></div>
</div>
<p>在这个例子中， <code class="xref py py-mod docutils literal notranslate"><span class="pre">echo</span></code> 和 <code class="xref py py-mod docutils literal notranslate"><span class="pre">surround</span></code> 模块是在执行 <code class="docutils literal notranslate"><span class="pre">from...import</span></code> 语句时导入到当前命名空间中的，因为它们定义在 <code class="xref py py-mod docutils literal notranslate"><span class="pre">sound.effects</span></code> 包中。（这在定义了 <code class="docutils literal notranslate"><span class="pre">__all__</span></code> 时也有效。）</p>
<p>虽然某些模块被设计为在使用 <code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">*</span></code> 时只导出遵循某些模式的名称，但在生产代码中它仍然被认为是不好的做法。</p>
<p>请记住，使用 <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">package</span> <span class="pre">import</span> <span class="pre">specific_submodule</span></code> 没有任何问题！ 实际上，除非导入的模块需要使用来自不同包的同名子模块，否则这是推荐的表示法。</p>
</div>
<div class="section" id="intra-package-references">
<h3><span class="section-number">6.4.2. </span>子包参考<a class="headerlink" href="#intra-package-references" title="永久链接至标题">¶</a></h3>
<p>当包被构造成子包时（与示例中的 <code class="xref py py-mod docutils literal notranslate"><span class="pre">sound</span></code> 包一样），你可以使用绝对导入来引用兄弟包的子模块。例如，如果模块 <code class="xref py py-mod docutils literal notranslate"><span class="pre">sound.filters.vocoder</span></code> 需要在 <code class="xref py py-mod docutils literal notranslate"><span class="pre">sound.effects</span></code> 包中使用 <code class="xref py py-mod docutils literal notranslate"><span class="pre">echo</span></code> 模块，它可以使用 <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">sound.effects</span> <span class="pre">import</span> <span class="pre">echo</span></code> 。</p>
<p>你还可以使用import语句的 <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">module</span> <span class="pre">import</span> <span class="pre">name</span></code> 形式编写相对导入。这些导入使用前导点来指示相对导入中涉及的当前包和父包。例如，从 <code class="xref py py-mod docutils literal notranslate"><span class="pre">surround</span></code> 模块，你可以使用:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">echo</span>
<span class="kn">from</span> <span class="nn">..</span> <span class="kn">import</span> <span class="n">formats</span>
<span class="kn">from</span> <span class="nn">..filters</span> <span class="kn">import</span> <span class="n">equalizer</span>
</pre></div>
</div>
<p>请注意，相对导入是基于当前模块的名称进行导入的。由于主模块的名称总是 <code class="docutils literal notranslate"><span class="pre">&quot;__main__&quot;</span></code> ，因此用作Python应用程序主模块的模块必须始终使用绝对导入。</p>
</div>
<div class="section" id="packages-in-multiple-directories">
<h3><span class="section-number">6.4.3. </span>多个目录中的包<a class="headerlink" href="#packages-in-multiple-directories" title="永久链接至标题">¶</a></h3>
<p>包支持另一个特殊属性， <a class="reference internal" href="../reference/import.html#__path__" title="__path__"><code class="xref py py-attr docutils literal notranslate"><span class="pre">__path__</span></code></a> 。它被初始化为一个列表，其中包含在执行该文件中的代码之前保存包的文件 <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> 的目录的名称。这个变量可以修改；这样做会影响将来对包中包含的模块和子包的搜索。</p>
<p>虽然通常不需要此功能，但它可用于扩展程序包中的模块集。</p>
<p class="rubric">备注</p>
<dl class="footnote brackets">
<dt class="label" id="id2"><span class="brackets"><a class="fn-backref" href="#id1">1</a></span></dt>
<dd><p>实际上，函数定义也是“被执行”的“语句”；模块级函数定义的执行在模块的全局符号表中输入该函数名。</p>
</dd>
</dl>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">目录</a></h3>
  <ul>
<li><a class="reference internal" href="#">6. 模块</a><ul>
<li><a class="reference internal" href="#more-on-modules">6.1. 更多有关模块的信息</a><ul>
<li><a class="reference internal" href="#executing-modules-as-scripts">6.1.1. 以脚本的方式执行模块</a></li>
<li><a class="reference internal" href="#the-module-search-path">6.1.2. 模块搜索路径</a></li>
<li><a class="reference internal" href="#compiled-python-files">6.1.3. “编译过的”Python文件</a></li>
</ul>
</li>
<li><a class="reference internal" href="#standard-modules">6.2. 标准模块</a></li>
<li><a class="reference internal" href="#the-dir-function">6.3. <code class="xref py py-func docutils literal notranslate"><span class="pre">dir()</span></code> 函数</a></li>
<li><a class="reference internal" href="#packages">6.4. 包</a><ul>
<li><a class="reference internal" href="#importing-from-a-package">6.4.1. 从包中导入 *</a></li>
<li><a class="reference internal" href="#intra-package-references">6.4.2. 子包参考</a></li>
<li><a class="reference internal" href="#packages-in-multiple-directories">6.4.3. 多个目录中的包</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="datastructures.html"
                        title="上一章"><span class="section-number">5. </span>数据结构</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="inputoutput.html"
                        title="下一章"><span class="section-number">7. </span>输入输出</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../bugs.html">提交 Bug</a></li>
      <li>
        <a href="https://github.com/python/cpython/blob/3.7/Doc/tutorial/modules.rst"
            rel="nofollow">显示源代码
        </a>
      </li>
    </ul>
  </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="inputoutput.html" title="7. 输入输出"
             >下一页</a> |</li>
        <li class="right" >
          <a href="datastructures.html" title="5. 数据结构"
             >上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python 教程</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>  
    <div class="footer">
    &copy; <a href="../copyright.html">版权所有</a> 2001-2020, Python Software Foundation.
    <br />
    Python 软件基金会是一个非盈利组织。
    <a href="https://www.python.org/psf/donations/">请捐助。</a>
    <br />
    最后更新于 6月 29, 2020.
    <a href="../bugs.html">发现了问题</a>？
    <br />
    使用<a href="http://sphinx.pocoo.org/">Sphinx</a>2.3.1 创建。
    </div>

  </body>
</html>